package org.example.utils.map;

import org.junit.Test;

import java.util.*;

/**
 * Map 遍历方式汇总
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2022/3/3 19:18
 */
public class MapTest1 {

    /**
     * Set<K> keySet()：拿到 map 中所有的 key，然后根据 key 获取 value.
     */
    @Test
    public void testKeySet1() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("id", 100);
        dataMap.put("name", "华南");
        dataMap.put("age", 33);
        Set<String> keySet = dataMap.keySet();
        for (String key : keySet) {
            System.out.println(key + " = " + dataMap.get(key));
        }
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            System.out.println(key + "->" + dataMap.get(key));
        }
    }

    /**
     * 【强制】使用Map的方法 keySet() / values() / entrySet() 返回集合对象时，
     * 不可以对其进行添加元素操作，否则会抛出 UnsupportedOperationException 异常。
     */
    @Test
    public void testKeySet2(){
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("id", 100);
        dataMap.put("name", "华南");
        dataMap.put("age", 33);

        Set<String> keySet = dataMap.keySet();
        // [name, id, age]
        System.out.println(keySet);

        keySet.remove("id");
        // [name, age]
        System.out.println(keySet);

        // 不能新增，否则报错.
        // keySet.add("msg");
    }

    /**
     * Collection<V> values()：获取所有的 value
     */
    @Test
    public void testValues() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("id", 100);
        dataMap.put("name", "华南");
        dataMap.put("age", 33);
        Collection<Object> values = dataMap.values();
        for (Object value : values) {
            System.out.println(value);
        }
        Iterator<Object> iterator = values.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    /**
     * Set<Map.Entry<K, V>> entrySet()：同时获取所有的 key 与 value
     */
    @Test
    public void testEntrySet() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("id", 100);
        dataMap.put("name", "华南");
        dataMap.put("age", 33);
        Set<Map.Entry<String, Object>> entrySet = dataMap.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
        Iterator<Map.Entry<String, Object>> iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            System.out.println(entry.getKey() + " > " + entry.getValue());
        }
    }

    /**
     * 如果是JDK8，使用Map.forEach方法
     */
    @org.junit.Test
    public void testForEach1() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("id", 100);
        dataMap.put("name", "华南");
        dataMap.put("age", 33);

        dataMap.forEach((key, value) -> {
            System.out.println(key + "=" + value);
        });
    }

    @org.junit.Test
    public void testForEach2() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("id", 100);
        dataMap.put("name", "华南");
        dataMap.put("age", 33);

        dataMap.entrySet().stream().forEach(entry -> {
            System.out.println(entry.getKey() + "=" + entry.getValue());
        });
    }

    /**
     * 删除 map 中的键值对，需要使用 {@link Iterator} 迭代器来删除.
     * 如果在遍历 map 的时候直接使用 {@link Map#remove(java.lang.Object)} 方法，
     * 则会有并发修改异常：java.util.ConcurrentModificationException
     */
    @Test
    public void testRemove() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("id", 100);
        dataMap.put("name", "华南");
        dataMap.put("age", 33);

        Iterator<String> iterator = dataMap.keySet().iterator();
        while (iterator.hasNext()) {
            if ("name".equals(iterator.next())) {
                iterator.remove();
            }
        }
        // {id=100, age=33}
        System.out.println(dataMap);

        /**
         * 比如下面这样做删除操作，就会抛出并发修改异常：java.util.ConcurrentModificationException
         */
        for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
            if (entry.getKey().equals("id")) {
                dataMap.remove(entry.getKey());
            }
        }
    }



}
